package android.translator;
import java.io.File;
import java.io.IOException;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.swt.widgets.Button;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.api.translate.Language;
import com.google.api.translate.Translate;

public class Translator {
	public static final String STRING="string";
	public static final String NAME="name";

	public static Map<String,Language> languageMap = new HashMap<String,Language>();
	static {
		// ACTION add or remove whatever languages you want to translate to
		//		languageMap.put(Language.ENGLISH, "");
		languageMap.put("en",Language.ENGLISH);
		languageMap.put("fr",Language.FRENCH);
		languageMap.put("ja",Language.JAPANESE);
		languageMap.put("de",Language.GERMAN);
		languageMap.put("es",Language.SPANISH);
		languageMap.put("it",Language.ITALIAN);
		languageMap.put("nl",Language.DUTCH);
		languageMap.put("za",Language.AFRIKAANS);
	}

	public static Document loadDocument(File d) throws ParserConfigurationException, SAXException, IOException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		if (d.exists()) {
			Document doc = db.parse(d);
			return doc;
		}
		else {
			Document doc = db.newDocument();
			Element rootElement = doc.createElement("resources");
			doc.appendChild(rootElement);
			return doc;
		}
	}

	public static String getStringResource(Document doc, String nameElement) {
		try {
			NodeList nodeLst = doc.getElementsByTagName(STRING);

			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				String nameKey = fstNode.getAttributes().getNamedItem("name").getNodeValue();
				if (nameElement.equals(nameKey)) {
					return fstNode.getTextContent();
				}
			}
		}
		catch (Throwable t) {
			return null;
		}
		return null;
	}

	public static void setStringResource(Document doc, String nameElement, String value) {
		try {
			NodeList nodeLst = doc.getElementsByTagName(STRING);

			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				String nameKey = fstNode.getAttributes().getNamedItem("name").getNodeValue();
				if (nameElement.equals(nameKey)) {
					fstNode.setTextContent(value);
					return;
				}
			}

			// no existing element found, create a new one
			Element newNameElement = doc.createElement(STRING);
			newNameElement.setAttribute("name", nameElement);
			newNameElement.appendChild(doc.createTextNode(forXML(value)));
			doc.getDocumentElement().appendChild(newNameElement);
		}
		catch (Throwable t) {
			t.printStackTrace();
		}
	}

	public static void TranslateSoft(File src, File dest, Language sourceL, Language destL) throws Exception {
		// ACTION Set the HTTP referrer to your website address.
		Translate.setHttpReferrer("http://google.com");

		try {
			Document doc = loadDocument(src);
			Document translatedDoc = loadDocument(dest);

			doc.getDocumentElement().normalize();

			NodeList nodeLst = doc.getElementsByTagName(STRING);

			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				String resourceName = fstNode.getAttributes().getNamedItem(NAME).getNodeValue();
				try {
					String translated;
					if ((translated=getStringResource(translatedDoc,resourceName))==null) {
						translated = Translate.execute(fstNode.getTextContent(), sourceL, destL);
						System.out.println("Translated "+resourceName+"="+translated);
					}
					else {
						System.out.println("Skipping "+resourceName+"="+translated);
					}
					setStringResource(translatedDoc,resourceName,translated);
				}
				catch (Exception e) {
					// on exception put the original text in
					setStringResource(translatedDoc,resourceName,fstNode.getTextContent());
				}
			}
			//write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
			DOMSource source = new DOMSource(translatedDoc);
			StreamResult result =  new StreamResult(dest);
			transformer.transform(source, result);
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String forXML(String aText){
		final StringBuilder result = new StringBuilder();
		final StringCharacterIterator iterator = new StringCharacterIterator(aText);
		char character =  iterator.current();
		while (character != CharacterIterator.DONE ){
			if (character == '<') {
				result.append("&lt;");
			}
			else if (character == '>') {
				result.append("&gt;");
			}
			else if (character == '\"') {
				result.append("\\\"");
			}
			else if (character == '\'') {
				result.append("\\'");
			}
			else if (character == '&') {
				result.append("&amp;");
			}
			else {
				//the char is not a special one
				//add it to the result as is
				result.append(character);
			}
			character = iterator.next();
		}
		return result.toString();
	}



	//	private static void addAttributes(NamedNodeMap attributes,	Element nameElement) {
	//		for (int i = 0; i < attributes.getLength(); i++) {
	//			Node a = attributes.item(i);
	//			nameElement.setAttribute(a.getNodeName(), a.getNodeValue());
	//		}
	//	}

//	public static void main(String[] args) throws Exception {
//		// ACTION edit the location of the resource file to translate
//		String srcResourceFile = "~/workspace/????/res/values/strings.xml";//"C:/workspaces/workspace.galileo/????/res/values/strings.xml";
//		// ACTION specify the source language of the file to translate
//		Language srcLanguage = Language.ENGLISH;
//
//		File src = new File(srcResourceFile);
//		File destDir, dest;
//		for (Language destLanguage : languageMap.keySet()) {
//			if (destLanguage!=srcLanguage) {
//				destDir = new File(src.getParentFile().getParentFile().getCanonicalPath()+File.separator+"values"+languageMap.get(destLanguage));
//				destDir.mkdirs();
//				dest = new File(src.getParentFile().getParentFile().getCanonicalPath()+File.separator+"values"+languageMap.get(destLanguage)+File.separator+"strings.xml");
//				System.out.println("Creating file :"+dest.getCanonicalPath());
//				TranslateSoft(src, dest, srcLanguage, destLanguage);
//			}
//		}
//
//	}

	public static String[] getLanguages() {
		Object[] langObj = Language.values();
		List<Language>all = new ArrayList<Language>();
		for (int i = 0; i < langObj.length; i++) {
			if (((Language)langObj[i])!=Language.AUTO_DETECT) {
				all.add((Language) langObj[i]);
			}
		}
		String[] lang = new String[all.size()];
		for (int i = 0; i < lang.length;i++) {
			lang[i] = all.get(i).name();
		}
		return lang;
	}

	public static int getDefault() {
		String[] lang = getLanguages();
		for (int i = 0; i < lang.length; i++) {
			if (lang[i].equals(Language.ENGLISH.name()))
				return i;
		}
		return 0;
	}

	public static void setLanguageSelection(String resource, List<Button> targetSelection) {
		System.out.println("----------->"+resource);
		if (resource.indexOf('-')>0)
			resource = resource.substring(resource.indexOf('-')+1);
		else
			resource = "en";
		System.out.println("Looking for resource "+resource);
		Language language = languageMap.get(resource);
		System.out.println("Mapped to language "+language.name());
		for (Button b : targetSelection) {
			if (b.getText().equals(language.name())) {
				b.setSelection(true);
				return;
			}
		}
		
	}
}
